//
//  WxLogin.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/1/11.
//

import Foundation
import SwiftUI
import LeanCloud
import AVFoundation

class CloudConfigImpl : ConfigProtocol {
    
    var totalCapacity = 0
    var usedCapacity = 0

    init() {
        queryCloudCapacity()
        queryUsedCloudCapacity()
    }
    
    /**
     * 查询云相册容量
     */
    private func queryCloudCapacity() {
        Task {
            if !userManager.isLogin() {
                totalCapacity = 0
                return
            }
            try await retry(maxRetries: 5, retryDelayMillis: 200) {
                let curTime = getMillisecond(try await getNetTime())
                let query = LCQuery(className: "CloudCapacity")
                query.whereKey("userId", .equalTo(userManager.getUserId()))
                //查询过期时间大于现在的
                query.whereKey("expirationTime", .greaterThanOrEqualTo(curTime))
                let list = try await LeancloudManager.instance.getList(query: query, modeType: CloudCapacityBean.self)
                var totalCount = 0
                list.forEach {
                    totalCount += $0.count ?? 0
                }
                self.totalCapacity = totalCount
                showLog("总容量：\(self.totalCapacity)")
            }
        }
    }
    
    /**
     * 查询已使用的容量
     */
    private func queryUsedCloudCapacity() {
        Task {
            if !userManager.isLogin() {
                usedCapacity = 0
                return
            }
            try await retry(maxRetries: 5, retryDelayMillis: 200) {
                let query = LCQuery(className: "CloudPicture")
                query.whereKey("userId", .equalTo(userManager.getUserId()))
                query.whereKey("cloudId", .notExisted)
                self.usedCapacity = query.count().intValue
                showLog("已使用容量：\(self.usedCapacity)")
            }
        }
    }
    
    
    func getFolderConfig()  async throws -> FolderConfig {
        userManager.user?.folderConfig ?? FolderConfig()
    }
    
    func saveFolderConfig(bean: FolderConfig) async throws {
        if let user = userManager.user {
            user.folderConfig = bean
            try await LeancloudManager.instance.save(todo: user)
            userManager.saveUser(user)
        }
        
    }
    
    func createMainFolderDB(folder : CloudFolderBean?) async throws {
        try check(userManager.isLogin(), "当前是官方备份，请先登录账号才可使用")
        try check(folder != nil, "数据不能为空")
        if let folder = folder{
            //保存云目录
            let dbFolderMainId = try await LeancloudManager.instance.saveToId(todo: folder)
            //保存云配置
            let config = try await getFolderConfig()
            config.dbFolderMainId = dbFolderMainId
            userManager.user?.folderConfig = config
            if let user = userManager.user {
                try await LeancloudManager.instance.save(todo: user)
            }
        }
    }
    
    func clearRoleList() {
        //代理那边处理
    }
    
    
    func getAiRole(roleId: String?) async throws -> AiRoleBean {
        //代理那边处理
        AiRoleBean()
    }
    
    func getSelectAiRoleList() async throws -> [AiRoleBean] {
        //代理那边处理
        return []
    }
    
    func getAiRoleList(_ force: Bool = false) async throws -> [AiRoleBean] {
        if !userManager.isLogin() {
            //退出登陆，数据要清空
            return []
        }
        let list = try await retry(maxRetries: 3, retryDelayMillis: 100) {
            let query = LCQuery(className: "AiRole")
            query.whereKey("userId", .equalTo(userManager.getUserId()))
            query.whereKey("sort", .ascending) //升序
            return try await LeancloudManager.instance.getList(query: query, modeType: AiRoleBean.self)
        }
        return list
    }
    
    func addAiRole(bean: AiRoleBean, isAdd: Bool) async throws -> AiRoleBean {
        let id = try await LeancloudManager.instance.saveToId(todo: bean)
        bean.objectId = id
        return bean
    }
    
    func delAiRole(bean: AiRoleBean) async throws {
        try await LeancloudManager.instance.del(todo: bean)
    }
    
    func selectAiRole(list: [AiRoleBean]) async throws {
        let config = try await getFolderConfig()
        config.aiRoleList = list.map { $0.objectId ?? "" }
        if let user = userManager.user {
            user.folderConfig = config
            try await LeancloudManager.instance.save(todo: user)
            userManager.saveUser(user)
        }
    }
    
    
    func getTagList() async throws -> [TagBean] {
        let query = LCQuery(className: "tag")
        query.whereKey("userId", .equalTo(userManager.getUserId()))
        query.whereKey("sort", .descending) //降序
        return try await LeancloudManager.instance.getList(query: query, modeType: TagBean.self)
    }
    
    func upload(image: UIImage, name: String) async throws -> CloudPictureBean {
        let key = "diary/\(name)"
        let qiniuReturn = try await QiniuManager.shared.upload(image : image, key: key ,modeType: QiniuResult.self)
        let pictureBean = CloudPictureBean()
        pictureBean.name = key
        let letterNum = getPinyinInitials(pictureBean.name ?? "")
        pictureBean.letterNum = letterNum
        pictureBean.duration = 0
        pictureBean.width = Int(image.size.width)
        pictureBean.height = Int(image.size.height)
        //保存一份到本地，然后设置为oldPath，主要用于识别图片，由于ai无法读取官网的图片，不然就不需要，但是云盘的图片就可以，应该是官网的图片不支持海外读取
        _ = ImageFileManager.saveImage(image, name)
        pictureBean.oldPath = name
        setPicture(pictureBean, qiniuReturn)
        pictureBean.thumbnail = QiniuUtils.getCompressUrl(false, pictureBean.url ?? "", pictureBean.width ?? 0 ,pictureBean.height ?? 0)
        return pictureBean
    }
    
    func upload(url: URL, name: String) async throws -> CloudPictureBean {
        let key = "diary/\(name)"
        let qiniuReturn = try await QiniuManager.shared.upload(url : url, key: key ,modeType: QiniuResult.self)
        let pictureBean = CloudPictureBean()
        let info = await getVideoInfo(from: url)
        pictureBean.name = key
        pictureBean.duration = Int64(info?.duration ?? 0)
        pictureBean.width = Int(info?.width ?? 0)
        pictureBean.height = Int(info?.height ?? 0)
        setPicture(pictureBean, qiniuReturn)
        pictureBean.thumbnail = QiniuUtils.getCompressUrl(true, pictureBean.url ?? "", pictureBean.width ?? 0 ,pictureBean.height ?? 0)
        return pictureBean
    }
    
    private func setPicture(_ pictureBean:CloudPictureBean, _ qiniuReturn: QiniuResult) {
        if let int64Value = Int64(qiniuReturn.size ?? "0") {
            pictureBean.size = int64Value
        } else {
            pictureBean.size = 0
        }
        pictureBean.mimeType = qiniuReturn.mimeType
        pictureBean.url = qiniuReturn.getUrl()
        pictureBean.fileId = qiniuReturn.key ?? ""
    }
    
    func delUrl(fileId: String) async throws {
        _ = try await QiniuManager.shared.delete2(fileName: fileId, modeType: String.self)
    }
    
    func getUploadCapacity() -> Int {
        return min(totalCapacity - usedCapacity, 9)
    }
    
    func checkCloudCapacity() -> Bool {
        if !userManager.isLogin() {
            return false
        }
        if totalCapacity > usedCapacity {
            return true
        } else {
            //弹窗提示
            showTipsDialog(text: "容量不足无法添加图片视频，请及时补充容量包。是否前往购买容量包") {
                showLog("执行购买，暂未开放")
            }
            return false
        }
    }
    
    func setOften(roleId: String?) async throws {
        let config = try await getFolderConfig()
        config.aiRoleOften = roleId
        if let user = userManager.user {
            user.folderConfig = config
            try await LeancloudManager.instance.save(todo: user)
            userManager.saveUser(user)
        }
    }
    
    func getOften() async throws -> String? {
        let config = try await getFolderConfig()
        return config.aiRoleOften
    }
}
